// GraphRegAllocator.h
// Defines the class GraphRegAllocator
#ifndef GRAPHREGALLOCATOR_H
#define GRAPHREGALLOCATOR_H

#include "crossbit/common.h"
#include "crossbit/RegAllocator.h"
#include <map>
#include <set>
#include <deque>
//#include <vector>

namespace crossbit {

    //class TBlock;
    //class VInst;

    class GraphRegAllocator : public RegAllocator {
	public:
	    GraphRegAllocator( XTUint8 num_regs, CBOfSpillIn cb_spill_in, CBOfSpillOut cb_spill_out, CBOfRegToReg cb_regtoreg):RegAllocator(num_regs, cb_spill_in, cb_spill_out, cb_regtoreg) 
		{ 
			//reg4vars = NULL; 
		}
	    virtual ~GraphRegAllocator()
		{
			//if(reg4vars != NULL)
			//	delete reg4vars;
		}

		virtual void init(VBlock * vblock);
	    virtual XTRegNum regAlloc(XTRegNum vreg, RegAccessMode mode);
	    virtual XTRegNum regAllocForce(XTRegNum vreg, XTRegNum expect, RegAccessMode mode);
	    virtual XTRegNum regAllocForceExcept(XTRegNum vreg, XTRegNum except, RegAccessMode mode);

	    virtual void regAllocReserve(XTRegNum reg);
	    virtual void regAllocRelease(XTRegNum reg);

	private:
		void collectGraphInfo(VBlock * vblock);
        XTInt32 **interfereGraphGen();
        void regPreAllocAllVars(XTInt32 **interfere_graph, XTInt32 graph_dim, XTInt32 reg_num);
	          
            virtual void incrementVinstSeq()
							    	{
				    			 vinst_seq++;
            for(XTRegNum i=0;i<ra_num_of_reg;i++)
            {
              if(ra_reg_table[i].status==ALLOCATED)
              {
              XTRegNum vreg=ra_reg_table[i].mapped_to;
              //printf("This is %d ALLOCATED with %d\n",i,vreg);
              ra_vreg_spilledIn[vreg]=true;
              }
            }
						     	}
            virtual void regSpillIn(XTRegNum vreg,XTRegNum treg);
												virtual XTRegNum regSpillOut(XTRegNum vreg);
 
            //add by czj 2008-5-15
       typedef std::set<XTRegNum> RegList;
        typedef std::deque<RegList> RegLists;
        RegLists reg_lists;
		
		const	static  XTInt32 SAVEALLOC = 0x08;        
		const	static  XTInt32 VREG_MAX_NUM = 50;        
		XTInt32 size;
        XTInt32 lower_bound;
        XTInt32 upper_bound;
		XTInt32 canGraph;
        //XTInt32 *reg4vars;
        XTInt32 reg4vars[VREG_MAX_NUM];
										const static XTInt32 MAX_VREG_NUM=50;
          const static XTInt32 X86_TREG_NUM=8;
										RegUsage ra_reg_table[X86_TREG_NUM];
          bool ra_vreg_spilledIn[MAX_VREG_NUM];//whether Vreg is mappedto a treg.
	//	XTInt32 interfere_graph[VREG_MAX_NUM][VREG_MAX_NUM];
    };
    
}

#endif
